#!/bin/bash
{
	#////////////////////////////////////
	# DietPi Explorer. Bare-bones, no frills file man
	#
	#////////////////////////////////////
	# Created by Daniel Knight / daniel.knight@dietpi.com / dietpi.com
	#
	#////////////////////////////////////
	#
	# Info:
	# - Location: /boot/dietpi/dietpi-explorer
	#
	# Usage:
	# - dietpi-explorer		Interactive file browser mode
	# - dietpi-explorer 1		Select a file/dir mode, return result for other applications to /tmp/.dietpi-explorer_selected_location
	#				Return an error code when no selection is done
	# - dietpi-explorer 1 <path>	Select a file/dir mode, start from <path>
	#////////////////////////////////////

	# Start in $2, else in current dir, which needs to be stored before G_INIT navigates to /tmp/$G_PROGRAM_NAME
	TARGET_FP=${2:-$PWD}

	# Import DietPi-Globals --------------------------------------------------------------
	. /boot/dietpi/func/dietpi-globals
	readonly G_PROGRAM_NAME='DietPi-Explorer'
	G_INIT
	# Import DietPi-Globals --------------------------------------------------------------

	[[ $1 == 1 ]] && INPUT=$1 || INPUT=0

	CURRENT_DIRECTORY=

	CP_MODE=0 # 0=copy 1=move
	CP_SOURCE=
	CP_TARGET=

	Process_Copy_Move(){

		if (( $CP_MODE == 0 )); then

			G_EXEC_NOHALT=1 G_EXEC cp -a "$CP_SOURCE" "$CP_TARGET"/

		elif (( $CP_MODE == 1 )); then

			G_EXEC_NOHALT=1 G_EXEC mv "$CP_SOURCE" "$CP_TARGET"/

		fi

		# Reset for next run
		CP_MODE=0
		CP_SOURCE=
		CP_TARGET=

	}

	Select_Menu(){

		if [[ $TARGET_FP == '..' || $TARGET_FP == '/' ]]; then

			G_EXEC_NOEXIT=1 G_EXEC cd "$TARGET_FP"
			return 0

		fi

		local target_type_info='File'
		G_WHIP_DEFAULT_ITEM='Open'
		G_WHIP_MENU_ARRAY=('' '●─ Navigation')
		if [[ -f $TARGET_FP && $INPUT != 1 ]]; then # Disable open of files in select mode

			G_WHIP_MENU_ARRAY+=('Open' " : Open '$TARGET_FP' in nano (text editor)")

		elif [[ -d $TARGET_FP ]]; then

			target_type_info='Directory'
			G_WHIP_MENU_ARRAY+=('Open' " : Navigate to '$TARGET_FP'")

		fi

		if [[ $INPUT == 1 ]]; then

			[[ $target_type_info == 'File' ]] && G_WHIP_DEFAULT_ITEM='Select'
			G_WHIP_MENU_ARRAY+=('Select' " : Use '$CURRENT_DIRECTORY/$TARGET_FP'")

		else

			G_WHIP_MENU_ARRAY+=('' '●─ I/O operations ')
			G_WHIP_MENU_ARRAY+=('Rename' '')
			G_WHIP_MENU_ARRAY+=('Copy' '')
			G_WHIP_MENU_ARRAY+=('Move' '')

			if [[ $CP_SOURCE && -d $CURRENT_DIRECTORY/$TARGET_FP && $CP_SOURCE != $CURRENT_DIRECTORY/$TARGET_FP ]]; then

				if (( $CP_MODE == 0 )); then

					G_WHIP_MENU_ARRAY+=('Paste' " : Copy $CP_SOURCE to $CURRENT_DIRECTORY/$TARGET_FP/")

				elif (( $CP_MODE == 1 )); then

					G_WHIP_MENU_ARRAY+=('Paste' " : Move $CP_SOURCE to $CURRENT_DIRECTORY/$TARGET_FP/")

				fi

			fi

			G_WHIP_MENU_ARRAY+=('Delete' '')
			G_WHIP_MENU_ARRAY+=('' '●─ Permissions ')
			G_WHIP_MENU_ARRAY+=('Chown' ' : Set user and group ownership')
			G_WHIP_MENU_ARRAY+=('Chmod' ' : Set read/write/exec permissions')

		fi

		local chmod_current mode_current user_current group_current
		read -r chmod_current mode_current user_current group_current < <(stat -c '%a %A %U %G' "$CURRENT_DIRECTORY/$TARGET_FP")

		G_WHIP_MENU "$target_type_info: $CURRENT_DIRECTORY/$TARGET_FP
 - R/W/Exec permissions : $mode_current ($chmod_current)
 - User/Group ownership : $user_current:$group_current\n" || return 0

		if [[ $G_WHIP_RETURNED_VALUE == 'Open' ]]; then

			if [[ -d $TARGET_FP ]]; then

				G_EXEC_NOEXIT=1 G_EXEC cd "$TARGET_FP"

			else

				nano "$TARGET_FP"

			fi

		elif [[ $G_WHIP_RETURNED_VALUE == 'Select' ]]; then

			echo "$CURRENT_DIRECTORY/$TARGET_FP" > /tmp/.dietpi-explorer_selected_location
			exit 0

		elif [[ $G_WHIP_RETURNED_VALUE == 'Copy' ]]; then

			CP_SOURCE="$CURRENT_DIRECTORY/$TARGET_FP"
			CP_MODE=0

		elif [[ $G_WHIP_RETURNED_VALUE == 'Move' ]]; then

			CP_SOURCE="$CURRENT_DIRECTORY/$TARGET_FP"
			CP_MODE=1

		elif [[ $G_WHIP_RETURNED_VALUE == 'Paste' ]]; then

			CP_TARGET="$CURRENT_DIRECTORY/$TARGET_FP"
			Process_Copy_Move

		elif [[ $G_WHIP_RETURNED_VALUE == 'Rename' ]]; then

			G_WHIP_DEFAULT_ITEM=$TARGET_FP
			G_WHIP_INPUTBOX "Please enter a new name for '$TARGET_FP'" && G_EXEC_NOHALT=1 G_EXEC mv "$TARGET_FP" "$G_WHIP_RETURNED_VALUE"

		elif [[ $G_WHIP_RETURNED_VALUE == 'Delete' ]]; then

			G_WHIP_YESNO "Delete $CURRENT_DIRECTORY/$TARGET_FP?" && G_EXEC_NOHALT=1 G_EXEC rm -R "$CURRENT_DIRECTORY/$TARGET_FP"

		elif [[ $G_WHIP_RETURNED_VALUE == 'Chown' ]]; then

			G_WHIP_MENU_ARRAY=()
			while read -r line
			do
				G_WHIP_MENU_ARRAY+=( "$line" '' )

			done < <(getent passwd | cut -d: -f1 | sort)

			G_WHIP_DEFAULT_ITEM=$user_current
			G_WHIP_MENU 'Chown permissions:\n - Please select a User' || return 0

			local user_target=$G_WHIP_RETURNED_VALUE

			G_WHIP_MENU_ARRAY=()
			while read -r line
			do
				G_WHIP_MENU_ARRAY+=( "$line" '' )

			done < <(getent group | cut -d: -f1 | sort)

			G_WHIP_DEFAULT_ITEM=$group_current
			G_WHIP_MENU 'Chown permissions:\n - Please select a Group' && G_EXEC_NOHALT=1 G_EXEC chown -R "$user_target:$G_WHIP_RETURNED_VALUE" "$CURRENT_DIRECTORY/$TARGET_FP"

		elif [[ $G_WHIP_RETURNED_VALUE == 'Chmod' ]]; then

			G_WHIP_DEFAULT_ITEM=$chmod_current
			G_WHIP_INPUTBOX 'Chmod permissions:\n - Please enter a value' && G_EXEC_NOHALT=1 G_EXEC chmod -R "$G_WHIP_RETURNED_VALUE" "$CURRENT_DIRECTORY/$TARGET_FP"

		fi

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# MENUS
	#/////////////////////////////////////////////////////////////////////////////////////
	TARGETMENUID=0

	# TARGETMENUID=0
	Menu_Main(){

		CURRENT_DIRECTORY=$PWD

		if [[ $CURRENT_DIRECTORY == '/' ]]; then

			CURRENT_DIRECTORY=
			G_WHIP_MENU_ARRAY=()

		else

			G_WHIP_MENU_ARRAY=(

				'..' 'Previous Directory'
				'/' 'Root Directory'

			)

		fi

		# Print info since this can take some seconds on slower drives and/or when large files are contained.
		# - Probably we should better scrape "ls -Al" and e.g. show owner and modes as well?
		echo -ne 'Scanning current directory...\r'

		for item in "$CURRENT_DIRECTORY"/{..?,.[^.],}*
		do
			if [[ -f $item ]]; then

				G_WHIP_MENU_ARRAY+=( "${item##*/}" ": $(wc -c < "$item") Bytes" )

			elif [[ -e $item || -L $item ]]; then

				G_WHIP_MENU_ARRAY+=( "${item##*/}" '' )

			fi
		done

		G_WHIP_BUTTON_CANCEL_TEXT='Exit'
		G_WHIP_DEFAULT_ITEM=$TARGET_FP
		if G_WHIP_MENU "$CURRENT_DIRECTORY"; then

			TARGET_FP=$G_WHIP_RETURNED_VALUE
			Select_Menu

		else

			Menu_Exit

		fi

	}

	Menu_Exit(){

		G_WHIP_SIZE_X_MAX=50
		G_WHIP_YESNO "Exit $G_PROGRAM_NAME?" && TARGETMENUID=-1 # Exit
		# In select mode, exit with error as indicator for parent script that no selection has been made
		[[ $INPUT == 1 ]] && exit 1

	}

	#/////////////////////////////////////////////////////////////////////////////////////
	# Main Loop
	#/////////////////////////////////////////////////////////////////////////////////////
	# Navigate to start dir
	G_EXEC_NOEXIT=1 G_EXEC cd "$TARGET_FP"

	# Start Menu
	until (( $TARGETMENUID < 0 ))
	do
		G_TERM_CLEAR
		Menu_Main
	done

	#-----------------------------------------------------------------------------------
	exit 0
	#-----------------------------------------------------------------------------------
}
